package com.umbacos.udm.client.model;

import java.util.ArrayList;
import java.util.HashMap;

import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.Response;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Label;
import com.umbacos.udm.client.arch.Popup;

public class Transmission {

	private ArrayList<TransSubscriber> subscribers = new ArrayList<TransSubscriber>();
	private JSONObject jo;
	private String sessionToken="";
	
    public static enum Settings{
    	DOWNLOAD_DIR, 
        PEER_LIMIT_GLOBAL, 
        PEER_LIMIT_PER_TORRENT, 
        RATIO_LIMIT,
        RATIO_LIMIT_ENABLED,
        RPC_AUTHENTICATION_REQUIRED,
        RPC_PASSWORD,
        RPC_USERNAME,
        SPEED_LIMIT_DOWN,
        SPEED_LIMIT_DOWN_ENABLED,
        SPEED_LIMIT_UP,
        SPEED_LIMIT_UP_ENABLED
    }

    public final HashMap<Settings,String> settingKey=new HashMap<Settings,String>();

    public Transmission(){
    	settingKey.put(Settings.DOWNLOAD_DIR, "download-dir");
    	settingKey.put(Settings.PEER_LIMIT_GLOBAL, "peer-limit-global");
    	settingKey.put(Settings.PEER_LIMIT_PER_TORRENT, "peer-limit-per-torrent");
    	settingKey.put(Settings.RATIO_LIMIT, "ratio-limit");
    	settingKey.put(Settings.RATIO_LIMIT_ENABLED, "ratio-limit-enabled");
    	settingKey.put(Settings.RPC_AUTHENTICATION_REQUIRED, "rpc-authentication-required");
    	settingKey.put(Settings.RPC_PASSWORD, "rpc-password");
    	settingKey.put(Settings.RPC_USERNAME, "rpc-username");
    	settingKey.put(Settings.SPEED_LIMIT_DOWN, "speed-limit-down");
    	settingKey.put(Settings.SPEED_LIMIT_DOWN_ENABLED, "speed-limit-down-enabled");
    	settingKey.put(Settings.SPEED_LIMIT_UP, "speed-limit-up");
    	settingKey.put(Settings.SPEED_LIMIT_UP_ENABLED, "speed-limit-up-enabled");
    }
    
	public void init(final RequestCallback rq) {
		
		AsyncComm ac=new AsyncComm();
		ac.addPostData("cmd", "t-read");
		ac.send(AsyncComm.TRAN, new RequestCallback() {
			
			@Override
			public void onResponseReceived(Request request, Response response) {
				if (response.getStatusCode()==200) {
					jo = new JSONObject(AsyncComm.JSON(response.getText()));
					}
				rq.onResponseReceived(request, response);				
			}
			
			@Override
			public void onError(Request request, Throwable exception) {
				rq.onError(request, exception);
			}
		});
	}
	
	public String getSetting(Settings key){
		return jo.get(settingKey.get(key)).toString().replace("\"","");
	}
	
	public void addSubscription(TransSubscriber ts) {
		subscribers.add(ts);
	}

	public void clearSubscription() {
		subscribers.clear();
	}

	private void publish(ArrayList<TransSubscriber> ts) {
		for (int i = 0; i < ts.size(); ++i)
			ts.get(i).update();
	}

	public void removeFileSubscription(TransSubscriber fs) {
		subscribers.remove(fs);
	}

	public interface TransSubscriber {
		public void update();
	}
	
	public void update(){
		if (sessionToken.length()==0){
			AsyncComm ac=new AsyncComm();
			ac.addPostData("cmd", "getsex");
			ac.send(AsyncComm.TRAN, new RequestCallback() {
				
				@Override
				public void onResponseReceived(Request request, Response response) {
					if (response.getStatusCode()==200) {
						String resp=response.getText();
						sessionToken = " --header \"" + resp.substring(4) + "\" -qO- ";
						update();
					} else {
						Popup pp=new Popup("Transmission Error", new Label(response.getStatusCode() + response.getStatusText()), Popup.POPUP_CLOSE);
						pp.showPopup();
					}					
				}
				
				@Override
				public void onError(Request request, Throwable exception) {
					Popup pp=new Popup("Transmission Error", new Label(exception.getMessage()), Popup.POPUP_CLOSE);
					pp.showPopup();
				}
			});
			
		} else {
			AsyncComm ac=new AsyncComm();
			ac.addPostData("cmd", "proxy");
			ac.addPostData("file", "method=session-get");
			ac.addPostData("para", sessionToken);
			ac.send(AsyncComm.TRAN, new RequestCallback() {
				
				@Override
				public void onResponseReceived(Request request, Response response) {
					if (response.getStatusCode()==200) {
						Window.alert(response.getText());
						publish(subscribers);
					} else {
						Popup pp=new Popup("Transmission Error", new Label(response.getStatusCode() + response.getStatusText()), Popup.POPUP_CLOSE);
						pp.showPopup();
					}					
				}
				
				@Override
				public void onError(Request request, Throwable exception) {
					Popup pp=new Popup("Transmission Error", new Label(exception.getMessage()), Popup.POPUP_CLOSE);
					pp.showPopup();
				}
			});
		}
	}
	
}
